﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Csla;
using Csla.Data;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;

namespace Asah.SiteWorx.Membership
{
    [Serializable()]
    public sealed class User
    {
        private Guid _id;
        private string _name;
        private string _email;

        public Guid ID
        {
            get
            {
                return _id;
            }
            internal set
            {
                _id = value;
            }
        }

        public string Name
        {
            get
            {
                return _name;
            }
            internal set
            {
                _name = value;
            }
        }

        public string Email
        {
            get
            {
                return _email;
            }
            internal set
            {
                _email = value;
            }
        }

        private User()
        {
            // force the use of the factory method.
        }

        public static User GetUser(Guid userId)
        {
            GetUserByIdCommand command;
            command = DataPortal.Execute<GetUserByIdCommand>(new GetUserByIdCommand(userId));

            User user = new User();
            user.ID = userId;
            user.Name = command.UserName;
            user.Email = command.Email;

            return user;
        }

        public static User GetUser(string userName)
        {
            GetUserByNameCommand command;
            command = DataPortal.Execute<GetUserByNameCommand>(new GetUserByNameCommand(userName));

            User user = new User();

            user.Name = userName;
            user.ID = command.UserId;
            user.Email = command.Email;

            return user;
        }

        #region GetUserByIdCommand

        [Serializable()]
        private class GetUserByIdCommand : CommandBase
        {
            private Guid _userId;
            private string _userName;
            private string _email;

            public string UserName
            {
                get
                {
                    return _userName;
                }
            }

            public string Email
            {
                get
                {
                    return _email;
                }
            }

            public GetUserByIdCommand(Guid userId)
            {
                _userId = userId;
            }

            protected override void DataPortal_Execute()
            {
                Database db = DatabaseFactory.CreateDatabase("SiteWorx");
                DbCommand dbCommand = db.GetStoredProcCommand("aspnet_Membership_GetUserByUserId");
                db.AddInParameter(dbCommand, "UserId", DbType.Guid, _userId);
                db.AddInParameter(dbCommand, "CurrentTimeUtc", DbType.DateTime, DateTime.Now);
                db.AddInParameter(dbCommand, "UpdateLastActivity", DbType.Boolean, false);

                try
                {
                    using (var dr = new SafeDataReader(db.ExecuteReader(dbCommand)))
                    {
                        if (dr.Read())
                        {
                            _userName = dr.GetString("UserName");
                            _email = dr.GetString("Email");
                        }
                    }
                    dbCommand.Dispose();
                }
                catch (Exception ex)
                {
                    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Layer Policy");
                    if (rethrow)
                    {
                        throw;
                    }
                }
            }
        }
        #endregion

        #region GetUserByNameCommand

        [Serializable()]
        private class GetUserByNameCommand : CommandBase
        {
            private string _userName;
            private Guid _userId;
            private string _email;

            public Guid UserId
            {
                get
                {
                    return _userId;
                }
            }

            public string Email
            {
                get
                {
                    return _email;
                }
            }

            public GetUserByNameCommand(string userName)
            {
                _userName = userName;
            }

            protected override void DataPortal_Execute()
            {
                Database db = DatabaseFactory.CreateDatabase("SiteWorx");
                DbCommand dbCommand = db.GetStoredProcCommand("aspnet_Membership_GetUserByName");
                db.AddInParameter(dbCommand, "ApplicationName", DbType.String, Site.GetSite().ApplicationName);
                db.AddInParameter(dbCommand, "UserName", DbType.String, _userName);
                db.AddInParameter(dbCommand, "CurrentTimeUtc", DbType.DateTime, DateTime.Now);
                db.AddInParameter(dbCommand, "UpdateLastActivity", DbType.Boolean, false);

                try
                {
                    using (var dr = new SafeDataReader(db.ExecuteReader(dbCommand)))
                    {
                        if (dr.Read())
                        {
                            _userId = dr.GetGuid("UserId");
                            _email = dr.GetString("Email");
                        }
                    }
                    dbCommand.Dispose();
                }
                catch (Exception ex)
                {
                    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Layer Policy");
                    if (rethrow)
                    {
                        throw;
                    }
                }
            }
        }
        #endregion

    }
}
